{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0a3fc0c3-e3db-44d6-8696-7b82e76ef020",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb0c6be9-1b21-4539-8b55-44778eaa9ea6",
   "metadata": {},
   "source": [
    "## 分组\n",
    "\n",
    "###  pandas中什么是分组操作?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b0792baf-dbce-42a0-be5d-8a297ce3506f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sex</th>\n",
       "      <th>class</th>\n",
       "      <th>Math</th>\n",
       "      <th>English</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>93</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>男</td>\n",
       "      <td>2</td>\n",
       "      <td>42</td>\n",
       "      <td>95</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>25</td>\n",
       "      <td>27</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>149</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>83</td>\n",
       "      <td>47</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>126</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>女</td>\n",
       "      <td>3</td>\n",
       "      <td>116</td>\n",
       "      <td>145</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>8</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>114</td>\n",
       "      <td>102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>男</td>\n",
       "      <td>4</td>\n",
       "      <td>44</td>\n",
       "      <td>49</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>42</td>\n",
       "      <td>64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>女</td>\n",
       "      <td>4</td>\n",
       "      <td>63</td>\n",
       "      <td>56</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>女</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>51</td>\n",
       "      <td>114</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>女</td>\n",
       "      <td>7</td>\n",
       "      <td>73</td>\n",
       "      <td>94</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>女</td>\n",
       "      <td>1</td>\n",
       "      <td>126</td>\n",
       "      <td>110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>女</td>\n",
       "      <td>3</td>\n",
       "      <td>7</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>男</td>\n",
       "      <td>4</td>\n",
       "      <td>106</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>女</td>\n",
       "      <td>8</td>\n",
       "      <td>28</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>男</td>\n",
       "      <td>5</td>\n",
       "      <td>143</td>\n",
       "      <td>85</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sex  class  Math  English\n",
       "0    男      6    93       15\n",
       "1    男      2    42       95\n",
       "2    男      1    25       27\n",
       "3    男      6   149        8\n",
       "4    男      1    83       47\n",
       "5    男      6   126       83\n",
       "6    女      3   116      145\n",
       "7    男      3     8       13\n",
       "8    男      1   114      102\n",
       "9    男      4    44       49\n",
       "10   男      6    42       64\n",
       "11   女      4    63       56\n",
       "12   女      1     6        5\n",
       "13   男      1    51      114\n",
       "14   女      7    73       94\n",
       "15   女      1   126      110\n",
       "16   女      3     7       29\n",
       "17   男      4   106        7\n",
       "18   女      8    28       17\n",
       "19   男      5   143       85"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df = pd.DataFrame(data={\n",
    "    'sex': np.random.randint(0, 2, size=20),\n",
    "    'class': np.random.randint(1, 9, size=20),\n",
    "    'Math': np.random.randint(0, 151, size=20),\n",
    "    'English': np.random.randint(0, 151, size=20),\n",
    "})\n",
    "df['sex'] = df['sex'].map({0: '男', 1: '女'})\n",
    "df['sex'].astype('object')\n",
    "\n",
    "display(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "6a8119b5-0595-4f65-8b21-329f16e52757",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name:  女\n",
      "data:     sex  class  Math  English\n",
      "6    女      3   116      145\n",
      "11   女      4    63       56\n",
      "12   女      1     6        5\n",
      "14   女      7    73       94\n",
      "15   女      1   126      110\n",
      "16   女      3     7       29\n",
      "18   女      8    28       17\n",
      "name:  男\n",
      "data:     sex  class  Math  English\n",
      "0    男      6    93       15\n",
      "1    男      2    42       95\n",
      "2    男      1    25       27\n",
      "3    男      6   149        8\n",
      "4    男      1    83       47\n",
      "5    男      6   126       83\n",
      "7    男      3     8       13\n",
      "8    男      1   114      102\n",
      "9    男      4    44       49\n",
      "10   男      6    42       64\n",
      "13   男      1    51      114\n",
      "17   男      4   106        7\n",
      "19   男      5   143       85\n"
     ]
    }
   ],
   "source": [
    "g = df.groupby(by='sex')\n",
    "for name, data in g:\n",
    "    print('name: ', name)\n",
    "    print('data: ', data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5846b505-c755-41e5-b133-d496b2d88c04",
   "metadata": {},
   "source": [
    "#### 多条件分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "569b76e3-3a2a-42a5-902b-bcee25e044e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "column info:  ('女', np.int64(1))\n",
      "data:     sex  class  Math  English\n",
      "12   女      1     6        5\n",
      "15   女      1   126      110\n",
      "column info:  ('女', np.int64(3))\n",
      "data:     sex  class  Math  English\n",
      "6    女      3   116      145\n",
      "16   女      3     7       29\n",
      "column info:  ('女', np.int64(4))\n",
      "data:     sex  class  Math  English\n",
      "11   女      4    63       56\n",
      "column info:  ('女', np.int64(7))\n",
      "data:     sex  class  Math  English\n",
      "14   女      7    73       94\n",
      "column info:  ('女', np.int64(8))\n",
      "data:     sex  class  Math  English\n",
      "18   女      8    28       17\n",
      "column info:  ('男', np.int64(1))\n",
      "data:     sex  class  Math  English\n",
      "2    男      1    25       27\n",
      "4    男      1    83       47\n",
      "8    男      1   114      102\n",
      "13   男      1    51      114\n",
      "column info:  ('男', np.int64(2))\n",
      "data:    sex  class  Math  English\n",
      "1   男      2    42       95\n",
      "column info:  ('男', np.int64(3))\n",
      "data:    sex  class  Math  English\n",
      "7   男      3     8       13\n",
      "column info:  ('男', np.int64(4))\n",
      "data:     sex  class  Math  English\n",
      "9    男      4    44       49\n",
      "17   男      4   106        7\n",
      "column info:  ('男', np.int64(5))\n",
      "data:     sex  class  Math  English\n",
      "19   男      5   143       85\n",
      "column info:  ('男', np.int64(6))\n",
      "data:     sex  class  Math  English\n",
      "0    男      6    93       15\n",
      "3    男      6   149        8\n",
      "5    男      6   126       83\n",
      "10   男      6    42       64\n"
     ]
    }
   ],
   "source": [
    "g = df.groupby(by=['sex', 'class'])\n",
    "for c, data in g:\n",
    "    print('column info: ', c)\n",
    "    print('data: ', data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44b54931-a1e1-4d96-9f11-8b7c4b29123b",
   "metadata": {},
   "source": [
    "### pandas中什么是分组聚合操作?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9f91e3e2-103a-488d-a598-b8d39d1173e4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>class</th>\n",
       "      <th>Math</th>\n",
       "      <th>English</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>女</th>\n",
       "      <td>3.857143</td>\n",
       "      <td>59.857143</td>\n",
       "      <td>65.142857</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>3.538462</td>\n",
       "      <td>78.923077</td>\n",
       "      <td>54.538462</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        class       Math    English\n",
       "sex                                \n",
       "女    3.857143  59.857143  65.142857\n",
       "男    3.538462  78.923077  54.538462"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "g = df.groupby(by='sex').mean()\n",
    "display(g)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "10ddb327-943e-4b3f-b9f0-eed625fbbbfb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>class</th>\n",
       "      <th>Math</th>\n",
       "      <th>English</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>女</th>\n",
       "      <td>8</td>\n",
       "      <td>126</td>\n",
       "      <td>145</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>6</td>\n",
       "      <td>149</td>\n",
       "      <td>114</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     class  Math  English\n",
       "sex                      \n",
       "女        8   126      145\n",
       "男        6   149      114"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "g = df.groupby(by='sex').max().round(2)\n",
    "display(g)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f9058ee5-ed28-47e5-8d11-54db85262745",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sex\n",
       "女     7\n",
       "男    13\n",
       "dtype: int64"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "g = df.groupby(by='sex').size().to_frame(name='人数')\n",
    "display(g)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "30939e14-c3b3-4133-9a62-6a505272909e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>class</th>\n",
       "      <th>Math</th>\n",
       "      <th>English</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>女</th>\n",
       "      <td>7</td>\n",
       "      <td>7</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>13</td>\n",
       "      <td>13</td>\n",
       "      <td>13</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     class  Math  English\n",
       "sex                      \n",
       "女        7     7        7\n",
       "男       13    13       13"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "g = df.groupby(by='sex').count()\n",
    "display(g)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7037d163-d551-431e-b98b-d523f339d8f6",
   "metadata": {},
   "source": [
    "### apply分组聚合如何操作?\n",
    "\n",
    "【案例】\n",
    "假设你有一个电力用户缴费的数据集,其中包含用户ID、缴费渠道、缴费金额等信息,你想要按照不同的缴费渠道,计算每种缴费渠道的平均缴费金额"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7b296f07-6d6f-4b04-a83f-6b2fafd92fa5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "0        1  Alipay  100\n",
       "1        2  WeChat  150\n",
       "2        3  Alipay  120\n",
       "3        4  WeChat  180\n",
       "4        5  Alipay   90\n",
       "5        6  Wechat  200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data={\n",
    "    'user_id': [1, 2, 3, 4, 5, 6],\n",
    "    '渠道': ['Alipay','WeChat','Alipay','WeChat','Alipay','Wechat'],\n",
    "    '金额': [100,150,120,180,90,200]\n",
    "}\n",
    "df = pd.DataFrame(data)\n",
    "display(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f3fba7b2-6e59-4671-b1af-8476dd9c49f8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/688516665.py:4: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
      "  res = df.groupby(by='渠道').apply(calculate_mean_payment)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>平均金额</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>渠道</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Alipay</th>\n",
       "      <td>103.333333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>WeChat</th>\n",
       "      <td>165.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wechat</th>\n",
       "      <td>200.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              平均金额\n",
       "渠道                \n",
       "Alipay  103.333333\n",
       "WeChat  165.000000\n",
       "Wechat  200.000000"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def calculate_mean_payment(group):\n",
    "    return group['金额'].mean()\n",
    "\n",
    "res = df.groupby(by='渠道').apply(calculate_mean_payment)\n",
    "res.to_frame(name='平均金额')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f17d48a4-e735-45e7-bc49-a8c35717fc9d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/3893296885.py:8: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
      "  res = df.groupby(by='渠道').apply(calculate_mean_payment)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>平均</th>\n",
       "      <th>最大</th>\n",
       "      <th>最小</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>渠道</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Alipay</th>\n",
       "      <td>103.33</td>\n",
       "      <td>120.0</td>\n",
       "      <td>90.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>WeChat</th>\n",
       "      <td>165.00</td>\n",
       "      <td>180.0</td>\n",
       "      <td>150.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wechat</th>\n",
       "      <td>200.00</td>\n",
       "      <td>200.0</td>\n",
       "      <td>200.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            平均     最大     最小\n",
       "渠道                          \n",
       "Alipay  103.33  120.0   90.0\n",
       "WeChat  165.00  180.0  150.0\n",
       "Wechat  200.00  200.0  200.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def calculate_mean_payment(group):\n",
    "    return pd.Series( {\n",
    "        '平均': group['金额'].mean().round(2),\n",
    "        '最大': group['金额'].max(),\n",
    "        '最小': group['金额'].min()\n",
    "    })\n",
    "\n",
    "res = df.groupby(by='渠道').apply(calculate_mean_payment)\n",
    "res"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02b6429d-580a-49bf-a02d-89338391d7a0",
   "metadata": {},
   "source": [
    "### transform分组聚合如何操作?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6f3ce152-57c3-48c3-a1b6-0e57b6362628",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "0        1  Alipay  100\n",
       "1        2  WeChat  150\n",
       "2        3  Alipay  120\n",
       "3        4  WeChat  180\n",
       "4        5  Alipay   90\n",
       "5        6  Wechat  200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data={\n",
    "    'user_id': [1, 2, 3, 4, 5, 6],\n",
    "    '渠道': ['Alipay','WeChat','Alipay','WeChat','Alipay','Wechat'],\n",
    "    '金额': [100,150,120,180,90,200]\n",
    "}\n",
    "df = pd.DataFrame(data)\n",
    "display(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e823a30b-34a3-4777-afaf-c4e7bc687007",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "渠道\n",
       "Alipay    103.333333\n",
       "WeChat    165.000000\n",
       "Wechat    200.000000\n",
       "Name: 金额, dtype: float64"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(by='渠道')['金额'].apply('mean')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "a39d656f-a60d-42b8-bf0f-91d379002fa2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>渠道</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Alipay</th>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>WeChat</th>\n",
       "      <td>165.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wechat</th>\n",
       "      <td>200.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            金额\n",
       "渠道            \n",
       "Alipay  103.33\n",
       "WeChat  165.00\n",
       "Wechat  200.00"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(by='渠道')[['金额']].apply('mean').round(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "ff608da9-7e05-4e33-929c-87faefffc9ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>平均金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>165.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>165.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>200.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     平均金额\n",
       "0  103.33\n",
       "1  165.00\n",
       "2  103.33\n",
       "3  165.00\n",
       "4  103.33\n",
       "5  200.00"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res = df.groupby(by='渠道')[['金额']].transform('mean').round(2)\n",
    "res.columns = ['平均金额']\n",
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "d5cfbf89-648e-4810-adc0-e594792a1b99",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "      <th>平均金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "      <td>165.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "      <td>165.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "      <td>103.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "      <td>200.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额    平均金额\n",
       "0        1  Alipay  100  103.33\n",
       "1        2  WeChat  150  165.00\n",
       "2        3  Alipay  120  103.33\n",
       "3        4  WeChat  180  165.00\n",
       "4        5  Alipay   90  103.33\n",
       "5        6  Wechat  200  200.00"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df, res, left_index=True, right_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "fa9c7ac7-5772-43a7-bd69-33ef7fe65a44",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "0        1  Alipay  100\n",
       "2        3  Alipay  120\n",
       "4        5  Alipay   90"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "1        2  WeChat  150\n",
       "3        4  WeChat  180"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "5        6  Wechat  200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/845433917.py:9: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
      "  res = df.groupby(by='渠道').apply(calculate_payment)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>平均</th>\n",
       "      <th>最大</th>\n",
       "      <th>最小</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>渠道</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Alipay</th>\n",
       "      <td>103.33</td>\n",
       "      <td>120.0</td>\n",
       "      <td>90.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>WeChat</th>\n",
       "      <td>165.00</td>\n",
       "      <td>180.0</td>\n",
       "      <td>150.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wechat</th>\n",
       "      <td>200.00</td>\n",
       "      <td>200.0</td>\n",
       "      <td>200.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            平均     最大     最小\n",
       "渠道                          \n",
       "Alipay  103.33  120.0   90.0\n",
       "WeChat  165.00  180.0  150.0\n",
       "Wechat  200.00  200.0  200.0"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def calculate_payment(group):\n",
    "    display(group)\n",
    "    return pd.Series( {\n",
    "        '平均': group['金额'].mean().round(2),\n",
    "        '最大': group['金额'].max(),\n",
    "        '最小': group['金额'].min()\n",
    "    })\n",
    "\n",
    "res = df.groupby(by='渠道').apply(calculate_payment)\n",
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "4e845b6f-85b1-451a-bfc4-399caeaa9a9d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "      <th>平均</th>\n",
       "      <th>最大</th>\n",
       "      <th>最小</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "      <td>103.33</td>\n",
       "      <td>120.0</td>\n",
       "      <td>90.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "      <td>165.00</td>\n",
       "      <td>180.0</td>\n",
       "      <td>150.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "      <td>103.33</td>\n",
       "      <td>120.0</td>\n",
       "      <td>90.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "      <td>165.00</td>\n",
       "      <td>180.0</td>\n",
       "      <td>150.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "      <td>103.33</td>\n",
       "      <td>120.0</td>\n",
       "      <td>90.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "      <td>200.00</td>\n",
       "      <td>200.0</td>\n",
       "      <td>200.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额      平均     最大     最小\n",
       "0        1  Alipay  100  103.33  120.0   90.0\n",
       "1        2  WeChat  150  165.00  180.0  150.0\n",
       "2        3  Alipay  120  103.33  120.0   90.0\n",
       "3        4  WeChat  180  165.00  180.0  150.0\n",
       "4        5  Alipay   90  103.33  120.0   90.0\n",
       "5        6  Wechat  200  200.00  200.0  200.0"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.merge(df, res, left_on='渠道', right_index=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6da4809-35af-4b1f-9527-c46e8adb4a90",
   "metadata": {},
   "source": [
    "### agg分组聚合如何操作? (处理多个函数)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "ca45c0f0-f248-457e-ae7d-ce1b431a5a08",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sex</th>\n",
       "      <th>class</th>\n",
       "      <th>Python</th>\n",
       "      <th>Math</th>\n",
       "      <th>Chinese</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>女</td>\n",
       "      <td>6</td>\n",
       "      <td>36</td>\n",
       "      <td>127</td>\n",
       "      <td>49</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>男</td>\n",
       "      <td>8</td>\n",
       "      <td>126</td>\n",
       "      <td>62</td>\n",
       "      <td>105</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>女</td>\n",
       "      <td>6</td>\n",
       "      <td>8</td>\n",
       "      <td>74</td>\n",
       "      <td>118</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>49</td>\n",
       "      <td>150</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>女</td>\n",
       "      <td>4</td>\n",
       "      <td>31</td>\n",
       "      <td>44</td>\n",
       "      <td>101</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>女</td>\n",
       "      <td>8</td>\n",
       "      <td>147</td>\n",
       "      <td>56</td>\n",
       "      <td>115</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>87</td>\n",
       "      <td>54</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>男</td>\n",
       "      <td>7</td>\n",
       "      <td>32</td>\n",
       "      <td>136</td>\n",
       "      <td>22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>女</td>\n",
       "      <td>8</td>\n",
       "      <td>125</td>\n",
       "      <td>32</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>女</td>\n",
       "      <td>7</td>\n",
       "      <td>86</td>\n",
       "      <td>132</td>\n",
       "      <td>62</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>女</td>\n",
       "      <td>2</td>\n",
       "      <td>123</td>\n",
       "      <td>15</td>\n",
       "      <td>49</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>96</td>\n",
       "      <td>136</td>\n",
       "      <td>132</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>女</td>\n",
       "      <td>6</td>\n",
       "      <td>68</td>\n",
       "      <td>49</td>\n",
       "      <td>38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>145</td>\n",
       "      <td>58</td>\n",
       "      <td>66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>女</td>\n",
       "      <td>6</td>\n",
       "      <td>138</td>\n",
       "      <td>16</td>\n",
       "      <td>19</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>女</td>\n",
       "      <td>3</td>\n",
       "      <td>30</td>\n",
       "      <td>97</td>\n",
       "      <td>98</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>女</td>\n",
       "      <td>2</td>\n",
       "      <td>41</td>\n",
       "      <td>125</td>\n",
       "      <td>107</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>女</td>\n",
       "      <td>3</td>\n",
       "      <td>121</td>\n",
       "      <td>122</td>\n",
       "      <td>84</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>女</td>\n",
       "      <td>2</td>\n",
       "      <td>91</td>\n",
       "      <td>50</td>\n",
       "      <td>67</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>女</td>\n",
       "      <td>8</td>\n",
       "      <td>36</td>\n",
       "      <td>67</td>\n",
       "      <td>65</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>72</td>\n",
       "      <td>110</td>\n",
       "      <td>141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>男</td>\n",
       "      <td>6</td>\n",
       "      <td>46</td>\n",
       "      <td>17</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>71</td>\n",
       "      <td>10</td>\n",
       "      <td>129</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>女</td>\n",
       "      <td>7</td>\n",
       "      <td>89</td>\n",
       "      <td>8</td>\n",
       "      <td>105</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>女</td>\n",
       "      <td>3</td>\n",
       "      <td>47</td>\n",
       "      <td>39</td>\n",
       "      <td>56</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>女</td>\n",
       "      <td>2</td>\n",
       "      <td>105</td>\n",
       "      <td>64</td>\n",
       "      <td>140</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>女</td>\n",
       "      <td>2</td>\n",
       "      <td>103</td>\n",
       "      <td>49</td>\n",
       "      <td>99</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>87</td>\n",
       "      <td>143</td>\n",
       "      <td>83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>女</td>\n",
       "      <td>5</td>\n",
       "      <td>68</td>\n",
       "      <td>48</td>\n",
       "      <td>38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>70</td>\n",
       "      <td>84</td>\n",
       "      <td>80</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sex  class  Python  Math  Chinese\n",
       "0    女      6      36   127       49\n",
       "1    男      8     126    62      105\n",
       "2    女      6       8    74      118\n",
       "3    男      6      49   150      121\n",
       "4    女      4      31    44      101\n",
       "5    女      8     147    56      115\n",
       "6    男      1      87    54      121\n",
       "7    男      7      32   136       22\n",
       "8    女      8     125    32        7\n",
       "9    女      7      86   132       62\n",
       "10   女      2     123    15       49\n",
       "11   男      3      96   136      132\n",
       "12   女      6      68    49       38\n",
       "13   男      6     145    58       66\n",
       "14   女      6     138    16       19\n",
       "15   女      3      30    97       98\n",
       "16   女      2      41   125      107\n",
       "17   女      3     121   122       84\n",
       "18   女      2      91    50       67\n",
       "19   女      8      36    67       65\n",
       "20   男      3      72   110      141\n",
       "21   男      6      46    17       18\n",
       "22   男      3      71    10      129\n",
       "23   女      7      89     8      105\n",
       "24   女      3      47    39       56\n",
       "25   女      2     105    64      140\n",
       "26   女      2     103    49       99\n",
       "27   男      1      87   143       83\n",
       "28   女      5      68    48       38\n",
       "29   男      3      70    84       80"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame(data = {\n",
    "    'sex': np.random.randint(0,2,size=30),#0男,1女\n",
    "    'class': np.random.randint(1,9,size=30),#1~8八个班\n",
    "    'Python': np.random.randint(0,151,size = 30), #Pythom成绩\n",
    "    'Math': np.random.randint(0,151,size=30), #Keras我绩\n",
    "    'Chinese': np.random.randint(0,151,size=30)\n",
    "})\n",
    "df['sex']=df['sex'].map({0:'男',1:'女'}) #将0,1映射成男女\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "4045b93d-892d-4fc8-bb5b-b98fc37b9866",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/2276857599.py:1: FutureWarning: The provided callable <function mean at 0x10c364180> is currently using SeriesGroupBy.mean. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"mean\" instead.\n",
      "  df.groupby(by='class')['Python'].agg([np.mean, np.median]).round(2)\n",
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/2276857599.py:1: FutureWarning: The provided callable <function median at 0x10c4f0180> is currently using SeriesGroupBy.median. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"median\" instead.\n",
      "  df.groupby(by='class')['Python'].agg([np.mean, np.median]).round(2)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mean</th>\n",
       "      <th>median</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>87.00</td>\n",
       "      <td>87.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>92.60</td>\n",
       "      <td>103.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>72.43</td>\n",
       "      <td>71.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>31.00</td>\n",
       "      <td>31.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>68.00</td>\n",
       "      <td>68.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>70.00</td>\n",
       "      <td>49.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>69.00</td>\n",
       "      <td>86.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>108.50</td>\n",
       "      <td>125.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         mean  median\n",
       "class                \n",
       "1       87.00    87.0\n",
       "2       92.60   103.0\n",
       "3       72.43    71.0\n",
       "4       31.00    31.0\n",
       "5       68.00    68.0\n",
       "6       70.00    49.0\n",
       "7       69.00    86.0\n",
       "8      108.50   125.5"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(by='class')['Python'].agg([np.mean, np.median]).round(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "ca0c2407-c829-45b2-976d-5fc74b4921f4",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/4254253556.py:1: FutureWarning: The provided callable <function mean at 0x10c364180> is currently using SeriesGroupBy.mean. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"mean\" instead.\n",
      "  df.groupby(by='class')[['Python', 'Math']].agg([np.mean, np.median]).round(2)\n",
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/4254253556.py:1: FutureWarning: The provided callable <function median at 0x10c4f0180> is currently using SeriesGroupBy.median. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"median\" instead.\n",
      "  df.groupby(by='class')[['Python', 'Math']].agg([np.mean, np.median]).round(2)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">Python</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Math</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>mean</th>\n",
       "      <th>median</th>\n",
       "      <th>mean</th>\n",
       "      <th>median</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>87.00</td>\n",
       "      <td>87.0</td>\n",
       "      <td>98.50</td>\n",
       "      <td>98.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>92.60</td>\n",
       "      <td>103.0</td>\n",
       "      <td>60.60</td>\n",
       "      <td>50.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>72.43</td>\n",
       "      <td>71.0</td>\n",
       "      <td>85.43</td>\n",
       "      <td>97.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>31.00</td>\n",
       "      <td>31.0</td>\n",
       "      <td>44.00</td>\n",
       "      <td>44.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>68.00</td>\n",
       "      <td>68.0</td>\n",
       "      <td>48.00</td>\n",
       "      <td>48.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>70.00</td>\n",
       "      <td>49.0</td>\n",
       "      <td>70.14</td>\n",
       "      <td>58.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>69.00</td>\n",
       "      <td>86.0</td>\n",
       "      <td>92.00</td>\n",
       "      <td>132.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>108.50</td>\n",
       "      <td>125.5</td>\n",
       "      <td>54.25</td>\n",
       "      <td>59.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Python          Math       \n",
       "         mean median   mean median\n",
       "class                             \n",
       "1       87.00   87.0  98.50   98.5\n",
       "2       92.60  103.0  60.60   50.0\n",
       "3       72.43   71.0  85.43   97.0\n",
       "4       31.00   31.0  44.00   44.0\n",
       "5       68.00   68.0  48.00   48.0\n",
       "6       70.00   49.0  70.14   58.0\n",
       "7       69.00   86.0  92.00  132.0\n",
       "8      108.50  125.5  54.25   59.0"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.groupby(by='class')[['Python', 'Math']].agg([np.mean, np.median]).round(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "5c6496d5-eeb9-4d96-94e3-45d7541140a3",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/3803942317.py:4: FutureWarning: The provided callable <function mean at 0x10c364180> is currently using SeriesGroupBy.mean. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"mean\" instead.\n",
      "  df2=df.groupby(by =['class','sex']).agg({\n",
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/3803942317.py:4: FutureWarning: The provided callable <function max at 0x10c357740> is currently using SeriesGroupBy.max. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"max\" instead.\n",
      "  df2=df.groupby(by =['class','sex']).agg({\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">Math</th>\n",
       "      <th>Python</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>最大差值</th>\n",
       "      <th>平均分</th>\n",
       "      <th>最大值</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <th>男</th>\n",
       "      <td>89</td>\n",
       "      <td>98.50</td>\n",
       "      <td>87</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <th>女</th>\n",
       "      <td>110</td>\n",
       "      <td>60.60</td>\n",
       "      <td>123</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>女</th>\n",
       "      <td>83</td>\n",
       "      <td>86.00</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>126</td>\n",
       "      <td>85.00</td>\n",
       "      <td>96</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <th>女</th>\n",
       "      <td>0</td>\n",
       "      <td>44.00</td>\n",
       "      <td>31</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <th>女</th>\n",
       "      <td>0</td>\n",
       "      <td>48.00</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">6</th>\n",
       "      <th>女</th>\n",
       "      <td>111</td>\n",
       "      <td>66.50</td>\n",
       "      <td>138</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>133</td>\n",
       "      <td>75.00</td>\n",
       "      <td>145</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">7</th>\n",
       "      <th>女</th>\n",
       "      <td>124</td>\n",
       "      <td>70.00</td>\n",
       "      <td>89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>0</td>\n",
       "      <td>136.00</td>\n",
       "      <td>32</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">8</th>\n",
       "      <th>女</th>\n",
       "      <td>35</td>\n",
       "      <td>51.67</td>\n",
       "      <td>147</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>0</td>\n",
       "      <td>62.00</td>\n",
       "      <td>126</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          Math         Python\n",
       "          最大差值     平均分    最大值\n",
       "class sex                    \n",
       "1     男     89   98.50     87\n",
       "2     女    110   60.60    123\n",
       "3     女     83   86.00    121\n",
       "      男    126   85.00     96\n",
       "4     女      0   44.00     31\n",
       "5     女      0   48.00     68\n",
       "6     女    111   66.50    138\n",
       "      男    133   75.00    145\n",
       "7     女    124   70.00     89\n",
       "      男      0  136.00     32\n",
       "8     女     35   51.67    147\n",
       "      男      0   62.00    126"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def delta(item):\n",
    "    return item.max() - item.min()\n",
    "    \n",
    "df2=df.groupby(by =['class','sex']).agg({\n",
    "    'Math':[('最大差值',delta),('平均分',np.mean)],\n",
    "    'Python':[('最大值', np.max)]\n",
    "    }).round(2)\n",
    "df2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "93b883da-e74f-4acb-ad9c-716d5caafb43",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/2547676956.py:6: FutureWarning: The provided callable <function mean at 0x10c364180> is currently using SeriesGroupBy.mean. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"mean\" instead.\n",
      "  df2=df.groupby(by =['class','sex']).aggregate({\n",
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/2547676956.py:6: FutureWarning: The provided callable <function max at 0x10c357740> is currently using SeriesGroupBy.max. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string \"max\" instead.\n",
      "  df2=df.groupby(by =['class','sex']).aggregate({\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">Math</th>\n",
       "      <th>Python</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>最大差值</th>\n",
       "      <th>平均分</th>\n",
       "      <th>最大值</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <th>男</th>\n",
       "      <td>89</td>\n",
       "      <td>98.50</td>\n",
       "      <td>87</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <th>女</th>\n",
       "      <td>110</td>\n",
       "      <td>60.60</td>\n",
       "      <td>123</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>女</th>\n",
       "      <td>83</td>\n",
       "      <td>86.00</td>\n",
       "      <td>121</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>126</td>\n",
       "      <td>85.00</td>\n",
       "      <td>96</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <th>女</th>\n",
       "      <td>0</td>\n",
       "      <td>44.00</td>\n",
       "      <td>31</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <th>女</th>\n",
       "      <td>0</td>\n",
       "      <td>48.00</td>\n",
       "      <td>68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">6</th>\n",
       "      <th>女</th>\n",
       "      <td>111</td>\n",
       "      <td>66.50</td>\n",
       "      <td>138</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>133</td>\n",
       "      <td>75.00</td>\n",
       "      <td>145</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">7</th>\n",
       "      <th>女</th>\n",
       "      <td>124</td>\n",
       "      <td>70.00</td>\n",
       "      <td>89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>0</td>\n",
       "      <td>136.00</td>\n",
       "      <td>32</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">8</th>\n",
       "      <th>女</th>\n",
       "      <td>35</td>\n",
       "      <td>51.67</td>\n",
       "      <td>147</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>0</td>\n",
       "      <td>62.00</td>\n",
       "      <td>126</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          Math         Python\n",
       "          最大差值     平均分    最大值\n",
       "class sex                    \n",
       "1     男     89   98.50     87\n",
       "2     女    110   60.60    123\n",
       "3     女     83   86.00    121\n",
       "      男    126   85.00     96\n",
       "4     女      0   44.00     31\n",
       "5     女      0   48.00     68\n",
       "6     女    111   66.50    138\n",
       "      男    133   75.00    145\n",
       "7     女    124   70.00     89\n",
       "      男      0  136.00     32\n",
       "8     女     35   51.67    147\n",
       "      男      0   62.00    126"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# pd.DataFrame.aggregate()\n",
    "\n",
    "def delta(item):\n",
    "    return item.max() - item.min()\n",
    "    \n",
    "df2=df.groupby(by =['class','sex']).aggregate({\n",
    "    'Math':[('最大差值',delta),('平均分',np.mean)],\n",
    "    'Python':[('最大值', np.max)]\n",
    "    }).round(2)\n",
    "df2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63202a36-73c6-4516-8f06-465df27f605f",
   "metadata": {},
   "source": [
    "### 不同分组聚合函数有什么区别呢?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "cdc6fc26-1044-4879-8746-6fc05549e503",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "0        1  Alipay  100\n",
       "1        2  WeChat  150\n",
       "2        3  Alipay  120\n",
       "3        4  WeChat  180\n",
       "4        5  Alipay   90\n",
       "5        6  Wechat  200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data={\n",
    "    'user_id': [1, 2, 3, 4, 5, 6],\n",
    "    '渠道': ['Alipay','WeChat','Alipay','WeChat','Alipay','Wechat'],\n",
    "    '金额': [100,150,120,180,90,200]\n",
    "}\n",
    "df = pd.DataFrame(data)\n",
    "display(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5e02968-5aef-4c11-b510-1e5dff798c61",
   "metadata": {},
   "source": [
    "### agg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62aaec31-c69e-4a67-81c8-93f4275847d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def convert(item):\n",
    "    display(item)\n",
    "    item['x'] = item['金额'] * item['user_id']\n",
    "    return item\n",
    "\n",
    "df.groupby(by='渠道').agg(convert)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07a7971d-79a9-4c4e-97af-c1cc5f026d41",
   "metadata": {},
   "source": [
    "#### apply"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "5875bbbd-e42b-495d-b198-60cbf5900d15",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "0        1  Alipay  100\n",
       "2        3  Alipay  120\n",
       "4        5  Alipay   90"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "1        2  WeChat  150\n",
       "3        4  WeChat  180"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id      渠道   金额\n",
       "5        6  Wechat  200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/var/folders/n2/fwhfgyqx3151x1fbxdrvm3rr0000gn/T/ipykernel_22800/3811165644.py:6: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
      "  df.groupby(by='渠道').apply(convert)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>渠道</th>\n",
       "      <th>金额</th>\n",
       "      <th>x</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>渠道</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">Alipay</th>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>100</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>120</td>\n",
       "      <td>360</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>Alipay</td>\n",
       "      <td>90</td>\n",
       "      <td>450</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">WeChat</th>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>150</td>\n",
       "      <td>300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>WeChat</td>\n",
       "      <td>180</td>\n",
       "      <td>720</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Wechat</th>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>Wechat</td>\n",
       "      <td>200</td>\n",
       "      <td>1200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          user_id      渠道   金额     x\n",
       "渠道                                  \n",
       "Alipay 0        1  Alipay  100   100\n",
       "       2        3  Alipay  120   360\n",
       "       4        5  Alipay   90   450\n",
       "WeChat 1        2  WeChat  150   300\n",
       "       3        4  WeChat  180   720\n",
       "Wechat 5        6  Wechat  200  1200"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def convert(item):\n",
    "    display(item)\n",
    "    item['x'] = item['金额'] * item['user_id']\n",
    "    return item\n",
    "\n",
    "df.groupby(by='渠道').apply(convert)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "169d0049-83b3-460c-9d26-cade3f03e533",
   "metadata": {},
   "source": [
    "### 什么是pivot透视表?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc598475-66e9-46c9-b6ce-a802f02fa813",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
